localhost 在 Container 中代表什麼Day 24 已經成功讓 Node.js 連線 PostgreSQL。
當時 Node.js 是直接執行在自己的電腦上,所以資料庫設定使用:
host: "localhost"
整個架構是:
Node.js(我的電腦)
│
↓
localhost:5432
│
↓
PostgreSQL Container
但如果今天把 Node.js 也放進 Docker,就不能再直接使用 localhost 連線 PostgreSQL。
這時候就需要再次用到 Day 9 學過的 Docker Network。
假設現在有兩個 Container:
Node.js Container
PostgreSQL Container
在 Node.js Container 裡:
localhost
代表的是 Node.js Container 自己。
所以如果 Node.js 使用:
host: "localhost"
它會在自己的 Container 裡尋找 PostgreSQL,當然就會連線失敗。
正確的方式是透過 Docker Network,使用 PostgreSQL 的 Service Name:
host: "postgres"
首先在 Node.js 專案中建立:
Dockerfile
內容如下:
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "app.js"]
這和前面 Day 11、Day 12 學過的 Dockerfile 概念相同。
Docker 會根據這份 Dockerfile 建立 Node.js Image。
接著把 Day 24 的:
host: "localhost"
修改成:
host: "postgres"
完整設定:
const client = new Client({
host: "postgres",
port: 5432,
user: "myuser",
password: "123456",
database: "schedule_db"
});
這裡的 postgres 就是 compose.yml 中設定的 Service Name。
接著修改 Compose:
services:
postgres:
image: postgres:17
container_name: my-postgres
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: 123456
POSTGRES_DB: schedule_db
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
app:
build: .
container_name: my-node-app
depends_on:
- postgres
volumes:
postgres-data:
現在 Compose 中有兩個服務:
services
│
├── postgres
│
└── app
其中:
build: .
代表使用目前資料夾中的 Dockerfile 建立 Node.js Image。
使用 Docker Compose 時,同一個 Compose 專案中的服務預設會加入同一個 Network。
所以不需要另外手動輸入:
docker network create
Node.js 可以直接透過:
postgres
找到 PostgreSQL。
架構變成:
Docker Network
│
├── app
│ │
│ └───────┐
│ ↓
└────── postgres:5432
這就是 Service Name 很重要的地方。
完成設定後執行:
docker compose up -d --build
其中:
up → 建立並啟動服務
-d → 背景執行
--build → 重新建立需要的 Image
接著查看:
docker compose ps
確認 PostgreSQL 與 Node.js Container 的狀態。
因為 Node.js 程式會查詢 PostgreSQL,可以使用:
docker compose logs app
如果成功,就可能看到:
PostgreSQL 連線成功!
[
{
id: 1,
name: '小明',
position: '正職'
}
]
這代表 Node.js Container 已經成功透過 Docker Network 找到 PostgreSQL Container。
現在已經不再是只有一個 Container。
而是:
Docker Compose
│
↓
Docker Network
│
├── Node.js Container
│ │
│ │ postgres:5432
│ ↓
└── PostgreSQL Container
│
↓
postgres-data
Volume
這樣 Node.js 和 PostgreSQL 都可以放在 Docker 中運作。
Compose 中使用:
depends_on:
- postgres
代表啟動時會先處理 PostgreSQL 的依賴關係。
但這不代表 PostgreSQL 一定已經完成初始化並準備接受連線。
如果 Node.js 一啟動就立刻連線,有時仍可能因 PostgreSQL 尚未準備完成而失敗。
之後正式開發時,可以加入 Health Check 或重試機制,讓服務之間的啟動更加穩定。
localhost → ✅ 改成 PostgreSQL Service Name postgres
docker compose up -d --build
docker compose logs app 查看錯誤compose.yml
localhost 改成 postgres
docker compose up -d --build
今天把 Node.js 也放進 Docker,並透過 Docker Network 連線 PostgreSQL。之前已經學過 Network,但當時只有單純理解 Container 之間可以互相連線,今天才真正把這個觀念應用在程式和資料庫上。
其中最容易搞混的還是 localhost。Node.js 在自己的電腦執行時可以使用 localhost,但進入 Container 後,localhost 就變成 Node.js Container 自己,因此要改成 PostgreSQL 的 Service Name postgres。
做到這裡,Node.js 和 PostgreSQL 已經可以一起透過 Docker Compose 管理。前面學過的 Dockerfile、Image、Container、Network、Volume 和 Compose 也幾乎全部串在一起了。